home *** CD-ROM | disk | FTP | other *** search
- //
- // Spinlocks should be used when the caller expects to need to touch
- // a piece of data for only a very short time. Interference on that
- // data will cause the later thread to spin (his processor does not
- // become available!)
- //
- // USE WITH CAUTION
- //
- // Modification History:
- //
- // 28-Dec-1989 JEF
- // Add class HC_Spinlock (for sequent symmetry only). This variation of
- // a spinlock works well when there is high contention for the lock.
- // After original by raj.
- //
-
- //
- // If compiling presto kernel, or compiling with preemption
- // included, then include code to make threads not preemptable
- // inside spinlock. Else, omit for speed.
- //
-
- //
- // For better locking performance, spinlocks should be compiled inline.
- // Note - this results in lots of warnings of the form:
- // .... warning: undeclared function S_LOCK() called
- // These can be ignored - C++ can't find the functions because they are
- // asm functions, which C++ doesn't know about. The functions are pulled
- // into the C++ C output via the +hasmdefs.h C++ flag prior to cc compilation.
- //
- #define DO_SPINLOCK_INLINE
-
- #ifdef DO_SPINLOCK_INLINE
- #define SPINLOCK_INLINE inline
- #else
- #define SPINLOCK_INLINE
- #endif
-
- #ifdef sequent
- #include "parallel.h"
- #endif sequent
- #ifdef sun
- #include "parallel.h"
- #endif sun
-
- #ifdef vax
- typedef int slock_t;
- #define L_UNLOCKED 0
-
- #define S_LOCK s_lock
- #define S_UNLOCK s_unlock
-
- //
- // For the vax, the underlying lock functions are in vax_lock.s and
- // spinlock.c. The s_lock and s_unlock functions do not return a
- // meaningful result.
- //
- #endif vax
- #ifdef sun
- #define S_LOCK s_lock
- #endif sun
-
- extern void s_init_lock(slock_t*);
- extern void s_lock(slock_t*);
- extern void s_unlock(slock_t*);
- extern int s_clock(slock_t*);
-
- class Thread;
-
- class Spinlock : public Object {
- slock_t sl_lock;
- #ifdef PROFILE
- int sl_q;
- #endif
- public:
- Spinlock(char *name = 0)
- {
- s_init_lock(&sl_lock);
- #ifdef PROFILE
- sl_q = SLInit(name);
- #endif
- }
- SPINLOCK_INLINE ~Spinlock();
-
- //
- // Acquire lock, spinning until it is free.
- //
- SPINLOCK_INLINE void lock();
-
- //
- // Acquire lock and return true iff lock is free, else return
- // false immediately without spinning.
- //
- int trylock()
- { return s_clock(&sl_lock); }
-
- //
- // Old name for trylock().
- //
- int checklock()
- { return trylock(); }
-
- //
- // Return true iff locked, else false.
- //
- int testlock()
- { return sl_lock; }
-
- //
- // Release lock.
- //
- SPINLOCK_INLINE void unlock();
- virtual void print(ostream& = cout);
- };
-
-
-
- //
- // High-contention spinlocks are only implemented on sequent symmetry.
- //
- #ifdef i386
- #include "parallel.h"
-
- class Thread;
-
- class HC_Spinlock : public Object {
- hc_slock_t sl_lock;
- #ifdef PROFILE
- int sl_q;
- #endif
- public:
- HC_Spinlock(char *name = 0)
- {
- HC_S_INIT_LOCK(&sl_lock);
- #ifdef PROFILE
- sl_q = SLInit(name);
- #endif
- }
-
- ~HC_Spinlock()
- {
- //
- // We should abort if the lock is not free. (?) XXX
- // For now just unlock it for backward compatibility.
- //
- if (testlock())
- unlock();
- #ifdef PROFILE
- SLDispose(sl_q);
- #endif
- }
-
- //
- // Acquire lock, spinning until it is free.
- //
- inline void lock();
-
- //
- // Acquire lock and return true iff lock is free, else return
- // false immediately without spinning.
- //
- int trylock() {
- cerr << "HC_Spinlock::trylock(): unimplemented\n";
- /* XXX for now, always returns FALSE */
- return (HC_S_CLOCK(&sl_lock));
- }
-
- //
- // Old name for trylock().
- //
- int checklock()
- { return (trylock()); }
-
- //
- // Return true iff locked, else false.
- //
- int testlock()
- { return HC_S_IS_LOCKED(&sl_lock); }
-
- //
- // Release lock.
- //
- inline void unlock();
- virtual void print(ostream& = cout);
- };
-
- #endif i386
-